package com.buddy.sds.auth.config;

import com.buddy.sds.auth.filter.Oauth2Filter;
import com.buddy.sds.auth.realm.OAuthRealm;
import com.buddy.sds.auth.realm.UsernamePasswordAuthRealm;
import com.buddy.sds.auth.realm.JWTAuthRealm;
import com.buddy.sds.auth.filter.JWTAuthFilter;
import com.buddy.sds.auth.filter.UsernamePasswordAuthFilter;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import javax.servlet.Filter;
import java.util.*;


@Slf4j
@Configuration
public class ShiroConfig {

    @Bean
    @Scope("prototype")
    public JWTAuthFilter jwtAuthFilter (){

        return new JWTAuthFilter();
    }

    @Bean
    @Scope("prototype")
    public UsernamePasswordAuthFilter usernamePasswordAuthFilter (){

        return new UsernamePasswordAuthFilter();
    }

    @Bean
    @Scope("prototype")
    public Oauth2Filter oauth2Filter (){

        return new Oauth2Filter();
    }


    @Bean
    public ShiroFilterFactoryBean shiroFilter(){

        log.info("初始化 shrioFilterFactoryBean");

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        shiroFilterFactoryBean.setSecurityManager(securityManager());


        Map<String, Filter> filterMap = new HashMap<>();

        filterMap.put("jwt",jwtAuthFilter());
        filterMap.put("usernamepassword",usernamePasswordAuthFilter());

        filterMap.put("oauth",oauth2Filter());
        //添加JWT认证过滤器
        //这里不要用Collections.singletonMap %>_<% 都是泪
        shiroFilterFactoryBean.setFilters(filterMap);


        //url<>过滤器
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        //注意过滤器配置顺序 不能颠倒
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了，登出后跳转配置的loginUrl
        filterChainDefinitionMap.put("/logout", "logout");
        // 配置不会被拦截的链接 顺序判断
      //  filterChainDefinitionMap.put("/auth/login", "anon");
        //将所有请求都转发到jwt过滤器
        filterChainDefinitionMap.put("/**", "jwt,oauth,usernamepassword");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        log.info("shrioFilterFactoryBean 初始化完毕");

        return shiroFilterFactoryBean;
    }



    @Bean
    public JWTAuthRealm jwtAuthRealm(){

        return new JWTAuthRealm();
    }

    @Bean

    public OAuthRealm oAuthRealm(){

        return new OAuthRealm();
    }

    @Bean
    public UsernamePasswordAuthRealm usernamePasswordAuthRealm(){

        return new UsernamePasswordAuthRealm();
    }



    @Bean
    public SecurityManager securityManager(){

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();


        //设置认证授权域 jwt认证和 账号密码认证
        securityManager.setRealms(Arrays.asList(jwtAuthRealm(),usernamePasswordAuthRealm(),oAuthRealm()));

        //关闭session
        DefaultSessionStorageEvaluator sessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);

        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator);

        securityManager.setSubjectDAO(subjectDAO);


        return securityManager;

    }
}
